#include <fstream>
#include <vector>
#include <string>
#include <queue>
#include <utility>

struct node;
class aut_comp;

struct node
{
    unsigned number, from;
    node * * next;
    bool terminal;
    std::vector<node *> * prev;
    node():
    number(0), next(0), prev(0), terminal(false), from(0)
    {
    }
    void init(unsigned alph_size);
    ~node();
};

class aut_comp
{
    unsigned n1_, n2_, alph_size_;
    char f_, l_;
    std::vector<node *> term1_, term2_;
    node * nodes1_,  * nodes2_, * start_, * stock_;
    unsigned get_ch_n_(char);
    void add_(node *, node *, char);
    unsigned num_(node *);
    node * g_node_(unsigned);
public:
    aut_comp(char, char);
    friend std::ifstream& operator>>(std::ifstream&, aut_comp&);
    std::string comp();
    ~aut_comp();
};

void node::init(unsigned a)
{
    next = new node*[a];
    for (unsigned i = 0; i < a; ++i)
    {
        next[i] = 0;
    }
    prev = new std::vector<node *>[a];
}

node::~node()
{
    delete[] next;
    delete[] prev;
}

aut_comp::aut_comp(char f, char l):
f_(f), l_(l), alph_size_(l - f + 1), start_(0), nodes1_(0), nodes2_(0)
{

}

unsigned aut_comp::get_ch_n_(char c)
{
    return c - f_;
}

unsigned aut_comp::num_(node * n)
{
    if (n == stock_)
    {
        return n1_ + n2_ + 1;
    }
    else
    {
        return (n->number + n1_ * n->from);
    }
}

node * aut_comp::g_node_(unsigned n)
{
    if (n == 0)
    {
        return start_;
    }
    else
    {
        if (n <= n1_)
        {
            return nodes1_ + n;
        }
        else
        {
            if (n == n1_ + n2_ + 1)
            {
                return stock_;
            }
            else
            {
                return nodes2_ + (n - n1_);
            }
        }
    }
}

std::ifstream& operator>> (std::ifstream& in, aut_comp& a)
{
    unsigned n, m, k, b, d;
    char c;
    in >> n >> m >> k;
    a.n1_ = n;
    if (!a.nodes1_)
    {
        delete[] a.nodes1_;
    }
    if (!a.nodes2_)
    {
        delete[] a.nodes2_;
    }
    a.term1_.clear();
    a.term2_.clear();
    a.nodes1_ = new node[n + 1];
    for (unsigned i = 1; i <= n; ++i)
    {
        a.nodes1_[i].init(a.alph_size_);
        a.nodes1_[i].from = 0;
        a.nodes1_[i].number = i;
    }
    for (unsigned i = 0; i < k; ++i)
    {
        in >> b;
        a.nodes1_[b].terminal = true;
        a.term1_.push_back(a.nodes1_ + b);
    }
    for (unsigned i = 0; i < m; ++i)
    {
        in >> b >> d >> c;
        a.add_(a.nodes1_ + b, a.nodes1_ + d, c);
    }
    in >> n >> m >> k;
    a.n2_ = n;
    a.nodes2_ = new node[n + 1];
    for (unsigned i = 1; i <= n; ++i)
    {
        a.nodes2_[i].init(a.alph_size_);
        a.nodes2_[i].from = 1;
        a.nodes2_[i].number = i;
    }
    for (unsigned i = 0; i < k; ++i)
    {
        in >> b;
        a.nodes2_[b].terminal = true;
        a.term2_.push_back(a.nodes2_ + b);
    }
    for (unsigned i = 0; i < m; ++i)
    {
        in >> b >> d >> c;
        a.add_(a.nodes2_ + b, a.nodes2_ + d, c);
    }
    a.start_ = new node;
    a.start_->init(a.alph_size_);
    if (a.n1_ > 0)
        a.add_(a.start_, a.nodes1_ + 1, 'a');
    if (a.n2_ > 0)
        a.add_(a.start_, a.nodes2_ + 1, 'a');
    return in;
}

void aut_comp::add_(node * b, node * e, char cw)
{
    unsigned c = get_ch_n_(cw);
    b->next[c] = e;
    e->prev[c].push_back(b);
}

std::string aut_comp::comp()
{
    unsigned summ = n1_ + n2_ + 2;
    bool * * diff = new bool*[summ];
    stock_ = new node;
    stock_->init(alph_size_);
    stock_->number = summ - 1;
    for (unsigned i = 0; i < summ; ++i)
    {
        diff[i] = new bool[summ];
        memset(diff[i], 0, sizeof(bool) * summ);
        for (unsigned c = 0; c < alph_size_; ++c)
        {
            if (!g_node_(i)->next[c])
            {
                add_(g_node_(i), stock_, c + f_);
            }
        }
    }
    std::queue<std::pair<node *, node *>> q;
    for (unsigned i = 0; i < term1_.size(); ++i)
    {
        for (unsigned j = 0; j < summ; ++j)
        {
            if (!diff[num_(term1_[i])][j] && !g_node_(j)->terminal)
            {
                q.push(std::pair<node *, node *>(term1_[i], g_node_(j)));
                diff[num_(term1_[i])][j] = true;
                diff[j][num_(term1_[i])] = true;
            }
        }
    }
    for (unsigned i = 0; i < term2_.size(); ++i)
    {
        for (unsigned j = 1; j < summ; ++j)
        {
            if (!diff[num_(term2_[i])][j] && !g_node_(j)->terminal)
            {
                q.push(std::pair<node *, node *>(term2_[i], g_node_(j)));
                diff[num_(term2_[i])][j] = true;
                diff[j][num_(term2_[i])] = true;
            }
        }
    }
    while (!q.empty())
    {
        node * a = q.front().first, * b = q.front().second;
        for (unsigned c = 0; c < alph_size_; ++c)
        {
            for (unsigned i = 0; i < a->prev[c].size(); ++i)
            {
                for (unsigned j = 0; j < b->prev[c].size(); ++j)
                {
                    if (a->prev[c][i] != b->prev[c][j] && !diff[num_(a->prev[c][i])][num_(b->prev[c][j])])
                    {
                        diff[num_(a->prev[c][i])][num_(b->prev[c][j])] = true;
                        diff[num_(b->prev[c][j])][num_(a->prev[c][i])] = true;
                        q.push(std::pair<node *, node *>(a->prev[c][i], b->prev[c][j]));
                    }
                }
            }
        }
        q.pop();
    }
    std::string ans;
    if (n1_ == 0 && n2_ == 0 || (term1_.size() == 0 && term2_.size() == 0))
    {
        ans.assign("YES");
    }
    else
        if ((n1_ == 0 || n2_ == 0) && (n1_ != n2_ && term1_.size() != term2_.size()))
        {
            ans.assign("NO");
        }
        else
        {
            if (diff[num_(nodes1_ + 1)][num_(nodes2_ + 1)])
            {
                ans.assign("NO");
            }
            else
            {
                ans.assign("YES");
            }
        }
    for (unsigned i = 0; i < summ; ++i)
    {
        delete[] diff[i];
    }
    delete diff;
    delete stock_;
    return ans;
}

aut_comp::~aut_comp()
{
    if (nodes1_)
        delete[] nodes1_;
    if (nodes2_)
        delete[] nodes2_;
    term1_.clear();
    term2_.clear();
}

int main()
{
    std::ifstream in("equivalence.in");
    std::ofstream out("equivalence.out");
    aut_comp a('a', 'z');
    in >> a;
    out << a.comp();
    return 0;
}